/*
* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* openUBMC is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*         http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/

#include "test_awm_m11p_common.h"

using namespace dev;

namespace drivers {
namespace pcie_gpu_card {
namespace innosilicon {
namespace awm_m11p_test {

// ========================= PCIeGpuCard设备测试 =========================

TEST_F(AwmM11pAbiTest, create_awm_m11p_card_success) {
    // 目标：验证PCIeGpuCard设备创建成功
    auto device_driver = m_devices["PCIeGpuCard"];
    ASSERT_TRUE(device_driver != nullptr);

    // 使用构造函数创建设备实例
    auto device = device_driver->ctor(&m_test_service, "awm_m11p_card");
    ASSERT_TRUE(device != nullptr);
}

TEST_F(AwmM11pAbiTest, init_awm_m11p_card_success) {
    // 目标：验证GPU卡设备的初始化功能
    auto device_driver = m_devices["PCIeGpuCard"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<awm_m11p_card*>(device_driver->ctor(&m_test_service, "awm_m11p_card_init"));
    ASSERT_TRUE(device != nullptr);

    // 设置SystemId配置
    auto config = create_test_csr();
    auto connector = create_test_connector();
    
    // 执行初始化
    status_t ret = device_driver->init(device, &config, &connector);
    EXPECT_EQ(ret, STATUS_OK);

}

TEST_F(AwmM11pAbiTest, start_stop_awm_m11p_card_success) {
    // 目标：验证GPU卡设备的基本启动和停止功能
    auto device_driver = m_devices["PCIeGpuCard"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<awm_m11p_card*>(device_driver->ctor(&m_test_service, "awm_m11p_card_start_stop"));
    ASSERT_TRUE(device != nullptr);

    auto config = create_test_csr();
    auto connector = create_test_connector();
    
    status_t init_ret = device_driver->init(device, &config, &connector);
    EXPECT_EQ(init_ret, STATUS_OK);

    status_t start_ret = device_driver->start(device);
    EXPECT_EQ(start_ret, STATUS_OK);
    
    status_t stop_ret = device_driver->stop(device);
    EXPECT_EQ(stop_ret, STATUS_OK);
}

TEST_F(AwmM11pAbiTest, basic_set_root_bdf) {
    // 目标：验证PCIeDevice的SetRootBDF和SetDeviceBDF功能
    auto device_driver = m_devices["PCIeGpuCard"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<awm_m11p_card*>(device_driver->ctor(&m_test_service, "awm_m11p_card_bdf"));
    ASSERT_TRUE(device != nullptr);

    // 测试无效BDF值
    EXPECT_FALSE(device->m_pcie_device.SetRootBDF(0x00, 0x00, 0x00));
    EXPECT_TRUE(device->m_pcie_device.SetRootBDF(0x01, 0x02, 0x03));
    
    // 测试无效Device BDF值
    EXPECT_FALSE(device->m_pcie_device.SetDeviceBDF(0x00, 0x00, 0x00));
    EXPECT_TRUE(device->m_pcie_device.SetDeviceBDF(0x01, 0x02, 0x03));
}

TEST_F(AwmM11pAbiTest, replace_dynamic_property) {
    // 目标：验证replace_dynamic_property功能
    auto device_driver = m_devices["PCIeGpuCard"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<awm_m11p_card*>(device_driver->ctor(&m_test_service, "awm_m11p_card_replace"));
    ASSERT_TRUE(device != nullptr);

    mc::mutable_dict object = mc::mutable_dict{{"bmc.dev.PCIeDevice", mc::mutable_dict{{"Slot", std::string("${Slot}")}}}};
    mc::dict connector{{"Slot", 0x00}};
    
    EXPECT_TRUE(device->replace_dynamic_property(object, connector));
    EXPECT_EQ(object["bmc.dev.PCIeDevice"]["Slot"].as<std::string>(), "0");
}

TEST_F(AwmM11pAbiTest, multiple_start_stop) {
    // 目标：验证多次启动和停止的稳定性
    auto device_driver = m_devices["PCIeGpuCard"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<awm_m11p_card*>(device_driver->ctor(&m_test_service, "awm_m11p_card_multiple"));
    ASSERT_TRUE(device != nullptr);

    auto config = create_test_csr();
    auto connector = create_test_connector();
    
    status_t init_ret = device_driver->init(device, &config, &connector);
    EXPECT_EQ(init_ret, STATUS_OK);

    for (int i = 0; i < 3; i++) {
        status_t start_ret = device_driver->start(device);
        EXPECT_EQ(start_ret, STATUS_OK);
        
        status_t stop_ret = device_driver->stop(device);
        EXPECT_EQ(stop_ret, STATUS_OK);
    }
}

TEST_F(AwmM11pAbiTest, multi_instance_awm_m11p_card) {
    // 目标：验证多实例创建和管理
    auto device_driver = m_devices["PCIeGpuCard"];
    ASSERT_TRUE(device_driver != nullptr);

    std::vector<void*> devices;
    for (int i = 0; i < 3; i++) {
        auto device = device_driver->ctor(&m_test_service, ("card_" + std::to_string(i)).c_str());
        ASSERT_TRUE(device != nullptr);
        devices.push_back(device);
    }

    // 清理
    for (auto device : devices) {
        device_driver->stop(device);
    }
}

} // namespace awm_m11p_test
} // namespace innosilicon
} // namespace pcie_gpu_card
} // namespace drivers
